package com.gonsin.gview.common.auth.session;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gonsin.base.exceptions.MyException;
import com.gonsin.gview.common.auth.AuthCommon;
import com.gonsin.gview.common.auth.BaseResultCodes;
import com.gonsin.gview.common.utils.SessionKeys;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

@Slf4j
public class JwtHttpSession implements HttpSession {
    private Map<String, Claim> localCache;
    
    public JwtHttpSession(String token, String secret){
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(AuthCommon.ISSUER)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            this.localCache = jwt.getClaims();

        // token超时错误
        } catch (TokenExpiredException ex) {
            throw new MyException(BaseResultCodes.USER_TIMEOUT);


        } catch (JWTVerificationException exception){
            exception.printStackTrace();
        }
    }

    @Override
    public long getCreationTime() {
        return 0;
    }

    @Override
    public String getId() {
        return "";
    }

    @Override
    public long getLastAccessedTime() {
        return 0;
    }

    @Override
    public ServletContext getServletContext() {
        return null;
    }

    @Override
    public void setMaxInactiveInterval(int interval) {
        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【setMaxInactiveInterval】");
    }

    @Override
    public int getMaxInactiveInterval() {
        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【getMaxInactiveInterval】");
    }

    @Override
    public HttpSessionContext getSessionContext() {
        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【getSessionContext】");
    }

    /**
     * 获取指定属性值
     * @param key 属性key
     * @return  key对应的value
     */
    @Override
    public Object getAttribute(String key) {
        Claim claim = localCache.get(key);
        return claim == null ? null : claim.asString();
//        Claim value = localCache.get(key);
//        return value.asString();
//        if(value == null){
//            if(sessionId != null){
//                value = cacheService.getCacheHash(sessionId, key);
//                if(value != null){
//                    localCache.put(key, value);
//                }
//                return value;
//            }
//        }
//        return value;
    }

    @Override
    public Object getValue(String name) {
        return getAttribute(name);
//        Claim value = localCache.get(name);
//        return value.asString();
//        Object value = localCache.get(name);
//        if(value == null){
//            if(sessionId != null){
//                value = cacheService.getCacheHash(sessionId, name);
//                if(value != null){
//                    localCache.put(name, value);
//                }
//                return value;
//            }
//        }
//        return value;
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        return null;
//        return localCache.getAttributeNames(sessionId);

//        return cacheService.getAttributeNames(sessionId);
    }

    @Override
    public String[] getValueNames() {
        Enumeration<String> values = getAttributeNames();
        if(values == null){
            return new String[0];
        }
        List<String> list = new ArrayList<>();
        while(values.hasMoreElements()){
            list.add(values.nextElement());
        }
        return list.toArray(new String[0]);
    }

    /**
     * 设置属性值
     * @param key           key
     * @param value         value
     */
    @Override
    public void setAttribute(String key, Object value) {
//        localCache.put(key, value);
//        cacheService.putCacheHash(sessionId, key, value, sessionTimeout);
//        cacheService.putCacheHash(sessionId, key, value);
        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【setAttribute】");
    }

    @Override
    public void putValue(String name, Object value) {
//        localCache.put(name, value);
//        cacheService.putCacheHash(sessionId, name, value, sessionTimeout);
//        cacheService.putCacheHash(sessionId, name, value);
        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【putValue】");
    }

    //session的过期时间,8小时

    //将sessionId存入浏览器
//    private void setCookieSessionId(String sessionId){
//        Cookie cookie = new Cookie(SESSIONID, sessionId);
//        cookie.setPath("/");
//        cookie.setMaxAge(sessionTimeout);
//        this.httpServletResponse.addCookie(cookie);
//    }

    /**
     * 移除指定的属性
     * @param key  属性 key
     */
    @Override
    public void removeAttribute(String key) {
//        cacheService.removeCacheHash(sessionId, key);
//        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【removeAttribute】");
//        localCache.remove(key);
//        if(sessionId == null){
//            cacheService.removeCacheHash(sessionId, key);
//        }
    }

    @Override
    public void removeValue(String name) {
//        cacheService.removeCacheHash(sessionId, name);
    }

    /**
     * session失效,删除当前用户的所有信息
     */
    @Override
    public void invalidate() {
//        cacheService.removeCacheHash(sessionId);
//        throw new MyException(BaseResultCodes.NOT_SUPPORT.getValue(), "不支持该方法【removeAttribute】");
//        localCache = new ConcurrentHashMap<>();
//        //删除在 redis 中的信息
//        if(sessionId != null){
//            cacheService.removeCacheHash(sessionId);
//            sessionId = null;
//            if(cookies != null){
//                for(Cookie cookie : cookies){
//                    if(SESSIONID.equals(cookie.getName())){
//                        //使cookie无效
//                        cookie.setMaxAge(0);
//                        cookie.setPath("/");
//                        httpServletResponse.addCookie(cookie);
//                        cookies = null;
//                        break;
//                    }
//                }
//            }
//        }
    }

    @Override
    public boolean isNew() {
        return false;
    }

    //浏览器的cookie key
    private static final String SESSIONID="gonsin_venus";


    //从浏览器获取SessionId
    private String getCookieSessionId(Cookie[] cookies){
        if(cookies != null){
            for(Cookie cookie : cookies){
                if(SESSIONID.equals(cookie.getName())){
                    return cookie.getValue();
                }
            }
        }
        return null;
    }

}
